package com.cxm.report.service.impl;

import com.cxm.report.dao.ChannelBrandReportDao;
import com.cxm.report.model.IReport;
import com.cxm.report.model.criteria.ReportFilter;
import com.cxm.report.model.data.ChannelBrandReport;
import com.cxm.report.model.data.ChannelReport;
import com.cxm.report.model.data.Report;
import com.cxm.report.model.event.MailEvent;
import com.cxm.report.service.ChannelBrandReportService;
import com.cxm.report.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author scl.BlueOcean
 * @version 1.0
 * @date 2018年07月02 18:14
 * @description
 */
@Service
public class ChannelBrandReportServiceImpl extends AbstractReportService implements ChannelBrandReportService {
    @Autowired
    private ChannelBrandReportDao channelBrandReportDao;

    @Override
    public List<Report> dayReport(ReportFilter filter) {
        List<ChannelBrandReport>  reportList = channelBrandReportDao.selectReports(filter);
        return getReports(reportList);
    }

    private void generateReport(List<Report> reports, String date, List<ChannelBrandReport> details) {
        Report report = new Report();
        report.setDate(date);
        LinkedHashMap<String, List<ChannelBrandReport>> reportMap = details.stream().collect(Collectors.groupingBy(ChannelBrandReport::getChannelName,
                LinkedHashMap::new, Collectors.toList()));
        report.setDetails(reportMap);

        //ChannelBrandReport total = caculateTotal(details);
        //report.setTotal(total);
        reports.add(report);
    }

    @Override
    public List<Report> timeScopeReport(ReportFilter filter) {
        List<Report> reports = new ArrayList<>();
        List<ChannelBrandReport>  reportList = channelBrandReportDao.selectReportsOfScope(filter);
        generateReport(reports,String.format("%s～%s",filter.getBegin(),filter.getEnd()),reportList);
        return reports;
    }

    @Override
    public List<Report> monthReport(ReportFilter filter) {
        List<ChannelBrandReport>  reportList = channelBrandReportDao.selectReportsGroupMonth(filter);
        return getReports(reportList);
    }


    @Override
    public List<Report> weekReport(ReportFilter filter) {
        List<ChannelBrandReport>  reportList = channelBrandReportDao.selectReportsGroupWeek(filter);
        List<Report> reports = getReports(reportList);
        setFirstAndLast(reports,filter);
        return reports;
    }

    private List<Report> getReports(List<ChannelBrandReport> reportList) {
        List<Report> reports = new ArrayList<>();
        //按照日期进行分组
        Map<String, List<ChannelBrandReport>> reportMap = reportList.stream().collect(Collectors.groupingBy(ChannelBrandReport::getReportDate, LinkedHashMap::new,Collectors.toList()));

        for (Map.Entry<String, List<ChannelBrandReport>> detailMap: reportMap.entrySet()) {
            generateReport(reports,detailMap.getKey(), detailMap.getValue());
        }
        return reports;
    }

    /**
     * 计算合计
     * @param details
     * @return
     */
    private ChannelBrandReport caculateTotal(List<ChannelBrandReport> details) {
        ChannelBrandReport total = details.stream().reduce(new ChannelBrandReport(),(x, y)->{
            x.setOrderNum(x.getOrderNum()+y.getOrderNum());
            x.setNoRecordNum(x.getNoRecordNum()+y.getNoRecordNum());
            x.setSuccessNum(x.getSuccessNum()+y.getSuccessNum());
            x.setOverTimeNum(x.getOverTimeNum()+y.getOverTimeNum());
            x.setInquiryNum(x.getInquiryNum()+y.getInquiryNum());
            x.setFailedNum(x.getFailedNum()+y.getFailedNum());
            x.setAvgQueryTime(x.getAvgQueryTime()+y.getSuccessNum()*y.getAvgQueryTime());
            return x;
        });
        total.setAvgQueryTime(total.getAvgQueryTime()/total.getSuccessNum());
        return total;

    }

    /**
     * 刷新数据
     * @param date
     */
    @Override
    public void refreshData(String date) {
        channelBrandReportDao.delete(date);
        channelBrandReportDao.insertBrandInfo(date);
        channelBrandReportDao.updateBrandName(date);
        channelBrandReportDao.updateChannelName(date);
        channelBrandReportDao.updateSuccessNum(date);
        channelBrandReportDao.updateFailedNum(date);
        channelBrandReportDao.updateNoRecordNum(date);
        channelBrandReportDao.updateOverTimeNum(date);
        channelBrandReportDao.updateInquiryNum(date);
    }

    private String getDefaultDate(String date) {
        if (!StringUtils.hasText(date)){
            date = DateUtil.currentDay();
        }
        return date;
    }
}
